﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExpenseSystem.Lor;
using ExpenseSystem.Fether;
using ExpenseSystem.Common;
using ExpenseSystem.Common.BaseModel;
using ExpenseSystem.DataUpdater.Validation;
using System.Web;

namespace ExpenseSystem.DataUpdater
{
    public class SystemDataUpdater<T>where T:SystemModel,new ()
    {
        private UserProfile login;
        public SystemDataUpdater()
        {
            login = HttpContext.Current.Session["login"] as UserProfile;
        }
        public event DataValidationHandler<T> DataUpdating;
        public event DataValidationHandler<T> DataDeleting;
        public virtual bool RemoveById(long[] idArray,string tran, SystemFetcher<T> fetcher, out string message)
        {
            if (login == null)
            {
                message = "登录用户为空";
                return false;
            }
            if (!login.Admin)
            {
                message = String.Format("登录id:{0}不是管理员", login.UserCode);
                return false;
            }
            
            int effectRows = 0;
            foreach (long id in idArray)
            {
                LogHelper.Info(GetType().FullName, String.Format("{1}对象正在删除AutoId={0}的记录", id, typeof(T).Name));
                if (id <= 0)
                {
                    message = String.Format("{1}对象传入的AutoId={0}不合法", id, typeof(T).Name);
                    LogHelper.Info(GetType().FullName, message);
                    continue;
                }
                T baseInDb = fetcher.Get( id, out message);
                if (baseInDb == null)
                {
                    message = String.Format("Remove正在尝试删除一个不存在的记录,类型为:{0}", typeof(T).FullName);
                    LogHelper.Info(GetType().FullName, message);
                    return false;
                }
                bool cancel = false;
                if (DataDeleting != null)
                {
                    LogHelper.Info(GetType().FullName, String.Format("对象{0}正在处理删除前的触发器", typeof(T).Name));
                    foreach (Delegate _invoker in DataDeleting.GetInvocationList())
                    {
                        DataValidationHandler<T> invoker = _invoker as DataValidationHandler<T>;
                        DataValidationEventArgs<T> eArg = new DataValidationEventArgs<T>() { Delete = baseInDb, Insert = null };
                        invoker.Invoke(this, eArg);
                        if (eArg.Cancle)
                        {
                            cancel = eArg.Cancle;
                            message = eArg.Message;
                            break;
                        }
                    }
                }
                if (cancel)
                {
                    message = String.Format("{1}对象数据删除校验程序不通过,AutoId={0}无法删除,原因是{2}", id, typeof(T).Name, message);
                    LogHelper.Info(GetType().FullName, message);
                    if (Variable.TERM_IN_ERR_BATCH)return false;else continue;
                }
                bool result = SqlProvider.GetDbInstance<T>().Delete(baseInDb, tran, out message);
                if (result)
                {
                    LogHelper.Info(GetType().FullName, String.Format("{1}对象的AutoId={0}的数据已被删除", id, typeof(T).Name));
                    effectRows += 1;
                }
                else
                {
                    LogHelper.Error(GetType().FullName, String.Format("{1}对象的AutoId={0}的数据删除失败,原因是{2}", id, typeof(T).Name, message));
                    if (Variable.TERM_IN_ERR_BATCH) return false; else continue;
                }
            }
            message = String.Format("受影响行数{0}行", effectRows);
            return effectRows > 0;
        }
        public virtual bool Remove(T data,string tran, SystemFetcher<T> fetcher,out string message)
        {
            if (login == null)
            {
                message = "登录用户为空";
                return false;
            }
            if (!login.Admin)
            {
                message = String.Format("登录id:{0}不是管理员", login.UserCode);
                return false;
            }
            if (data == null || String.IsNullOrWhiteSpace(tran))
            {
                message = String.Format("Remove方法异常，传入的参数为空,{0}", login.UserCode);
                return false;
            }
            LogHelper.Info(GetType().FullName, String.Format("{1}对象正在删除AutoId={0}的记录", data.AutoId, typeof(T).Name));
            if (data.AutoId <= 0)
            {
                message = String.Format("{1}对象传入的AutoId={0}不合法", data.AutoId, typeof(T).Name);
                LogHelper.Info(GetType().FullName, message);
                return false;
            }           
            T baseInDb = fetcher.Get( data.AutoId, out message);
            if (baseInDb == null)
            {
                message = String.Format("Remove正在尝试删除一个不存在的记录,类型为:{0}" , typeof(T).FullName);
                LogHelper.Info(GetType().FullName,message);
                return false;
            }
            if(baseInDb.Flag!=data.Flag)
            {
                message = String.Format("删除对象{1}失败,AutoId={0}的数据已失效", data.AutoId, typeof(T).Name, message);
                LogHelper.Info(GetType().FullName, message);
                return false;
            }
            
            bool cancel = false;
            if (DataDeleting != null)
            {
                LogHelper.Info(GetType().FullName, String.Format("对象{0}正在处理删除前的触发器", typeof(T).Name));
                foreach (Delegate _invoker in DataDeleting.GetInvocationList())
                {
                    DataValidationHandler<T> invoker = _invoker as DataValidationHandler<T>;
                    DataValidationEventArgs<T> eArg = new DataValidationEventArgs<T>() { Delete = baseInDb, Insert = null};
                    invoker.Invoke(this, eArg);
                    if (eArg.Cancle)
                    {
                        cancel = eArg.Cancle;
                        message = eArg.Message;
                        break;
                    }
                }
            }
            if (cancel)
            {
                message = String.Format("{1}对象数据删除校验程序不通过,AutoId={0}无法删除,原因是{2}", data.AutoId, typeof(T).Name, message);
                LogHelper.Info(GetType().FullName, message);
                return false;
            }
            bool result = SqlProvider.GetDbInstance<T>().Delete(data, tran, out message);
            if (result)
            {
                LogHelper.Info(GetType().FullName, String.Format("{1}对象的AutoId={0}的数据已被删除", data.AutoId, typeof(T).Name));
            }
            else
            {
                LogHelper.Error(GetType().FullName, String.Format("{1}对象的AutoId={0}的数据删除失败,原因是{2}", data.AutoId, typeof(T).Name, message));
            }
            return result;
        }
        public virtual bool Save(T data,string tran, SystemFetcher<T> fetcher,out string message)
        {
            if (login == null)
            {
                message = "登录用户为空";
                return false;
            }
            if (!login.Admin)
            {
                message = String.Format("登录id:{0}不是管理员", login.UserCode);
                return false;
            }
            if (data == null || String.IsNullOrWhiteSpace(tran))
            {
                message = "Save参数data及tran不能为空或空白";
                return false;
            }
            message = "";
            if (data.AutoId == 0 && data.Flag != 0)
            {
                message = String.Format("保存对象失败，对象{0}在AutoId=0的情况下，Flag必须为0", typeof(T).Name);
                return false;
            }
            T db = null;
            bool result = false;
            if (data.AutoId == 0)
            {
                LogHelper.Info(GetType().FullName, String.Format("新建的{0}对象开始保存", typeof(T).Name));
                db = null;
            }
            else
            {
                LogHelper.Info(GetType().FullName, String.Format("AutoId={0}的{1}对象开始保存", data.AutoId, typeof(T).Name));
                db = fetcher.Get( data.AutoId, out message);
                if (db == null)
                {
                    message = String.Format("{1}对象AutoId={0}不存在，可能已经被其他用户删除", data.AutoId, typeof(T).Name);
                    return false;
                }
            }
            bool cancel = false;
            if (DataUpdating != null)
            {
                LogHelper.Info(GetType().FullName, String.Format("对象{0}正在处理保存前的触发器", typeof(T).Name));
                foreach (Delegate _invoker in DataUpdating.GetInvocationList())
                {
                    DataValidationHandler<T> invoker = _invoker as DataValidationHandler<T>;
                    DataValidationEventArgs<T> eArg = new DataValidationEventArgs<T>() { Delete = db, Insert = data };
                    invoker.Invoke(this, eArg);
                    if (eArg.Cancle)
                    {
                        cancel = eArg.Cancle;
                        message = eArg.Message;
                        break;
                    }
                }
            }
            if (cancel)
            {
                message = String.Format("对象{1}数据保存校验程序不通过:{0}", message, typeof(T).Name);
                LogHelper.Info(GetType().FullName, message);
                return false;
            }
            UserProfile userProfile = HttpContext.Current.Session[Definition.SESSION_LOGIN_STR] as UserProfile;

            if (db == null)
            {
                db = new T();
            }
            data.Flag += 1;
            db.Merge(data);

            if (data.AutoId == 0)
            {
                if (userProfile != null)
                {
                    data.Creator = userProfile.UserCode;
                }
                data.CreateDate = DateTime.Now.ToString(Definition.DATETIME_FORMAT);
                data.Flag = 1;
                data.Avaliable = true;
                result = SqlProvider.GetDbInstance<T>().Insert(data, tran, out message);
            }
            else
            {
                if (userProfile != null)
                {
                    db.Modifier = userProfile.UserCode;
                }
                db.ModifyDate = DateTime.Now.ToString(Definition.DATETIME_FORMAT);
                result = SqlProvider.GetDbInstance<T>().Update(db, tran, out message);
            }
            if (result)
            {
                data.Flag += 1;
                LogHelper.Info(GetType().FullName, String.Format("{1}对象的AutoId={0}的数据已被成功保存", data.AutoId, typeof(T).Name));
            }
            else
            {
                LogHelper.Error(GetType().FullName, String.Format("{1}对象的AutoId={0}的数据保存失败,原因是{2}", data.AutoId, typeof(T).Name, message));
            } 
            return result;
        }
    }
}
